package tr.edu.ege.kipler.satisfiability.container.operational;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;

import tr.edu.ege.kipler.common.RelationalNode;
import tr.edu.ege.kipler.satisfiability.container.Individual;
import tr.edu.ege.kipler.syntax.Name;
import tr.edu.ege.kipler.syntax.Role;
import tr.edu.ege.kipler.syntax.atomicformula.ObjectRoleAssertion;

/**
 * 
 * @author İnanç Seylan
 *
 */
public class ObjectRoleAssertionIterator implements
		Iterator<ObjectRoleAssertion> {

	private class Data {
		private boolean successor;

		private Iterator<RelationalNode<Individual, Role, Name>> iterator;

		public Data(boolean successor,
				Iterator<RelationalNode<Individual, Role, Name>> iterator) {
			this.successor = successor;
			this.iterator = iterator;
		}

		/**
		 * @return the iterator
		 */
		public Iterator<RelationalNode<Individual, Role, Name>> getIterator() {
			return iterator;
		}

		/**
		 * @param iterator
		 *            the iterator to set
		 */
		public void setIterator(
				Iterator<RelationalNode<Individual, Role, Name>> iterator) {
			this.iterator = iterator;
		}

		/**
		 * @return the successor
		 */
		public boolean isSuccessor() {
			return successor;
		}

		/**
		 * @param successor
		 *            the successor to set
		 */
		public void setSuccessor(boolean successor) {
			this.successor = successor;
		}

	}

	private Map<Role, Data> dataMap = new HashMap<Role, Data>();

	private Iterator<Role> roleIter;

	private Role currRole;

	private Iterator<RelationalNode<Individual, Role, Name>> neighborIter;

	private boolean init = true;

	private Individual owner;

	public ObjectRoleAssertionIterator(Individual owner) {
		this.owner = owner;
	}

	private void init() {
		init = false;
		roleIter = dataMap.keySet().iterator();
		if (roleIter.hasNext()) {
			currRole = roleIter.next();
			neighborIter = dataMap.get(currRole).getIterator();
		}
	}

	private Iterator<RelationalNode<Individual, Role, Name>> getIterator() {
		Iterator<RelationalNode<Individual, Role, Name>> result = null;
		if (init) {
			init();
		}
		if (neighborIter != null) {
			while (roleIter.hasNext() && !neighborIter.hasNext()) {
				currRole = roleIter.next();
				neighborIter = dataMap.get(currRole).getIterator();
			}
			if (neighborIter.hasNext()) {
				result = neighborIter;
			}
		}
		return result;
	}

	public boolean hasNext() {
		return getIterator() != null;
	}

	public ObjectRoleAssertion next() {
		Iterator<RelationalNode<Individual, Role, Name>> iter = getIterator();
		if (iter == null) {
			throw new NoSuchElementException();
		}
		String indvName = iter.next().getValue().getName();
		ObjectRoleAssertion result;
		if (dataMap.get(currRole).isSuccessor()) {
			result = new ObjectRoleAssertion(currRole, owner.getName(),
					indvName);
		} else {
			result = new ObjectRoleAssertion(currRole, indvName, owner
					.getName());
		}
		return result;
	}

	public void remove() {
		// nothing to do
	}

	public void addSuccessorIterator(Role role,
			Iterator<RelationalNode<Individual, Role, Name>> iter) {
		dataMap.put(role, new Data(true, iter));
	}

	public void addPredecessorIterator(Role role,
			Iterator<RelationalNode<Individual, Role, Name>> iter) {
		dataMap.put(role, new Data(false, iter));
	}

}
